package org.quartz.watch.dc.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;

import javax.faces.event.ActionEvent;

import org.quartz.watch.QWLogger;
import org.quartz.watch.dc.QWControlledRecord;
import org.quartz.watch.dc.QWDialogController;

import com.icesoft.faces.component.datapaginator.DataPaginator;
import com.icesoft.faces.component.datapaginator.PaginatorActionEvent;
import com.icesoft.faces.component.menubar.MenuItem;
import com.icesoft.faces.context.DisposableBean;

public abstract  class  QWAbstractDC<R extends QWAbstractDC.Record<?>> implements QWDialogController<R>, DisposableBean {
	protected DataPaginator paginator;
	protected int pageSize;
	protected int maxPages;
	private R selectedRecord;
	private boolean skipDeleteWarning;
	private List<R> selectedRecords;
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#clean()
	 */
	public void clean() {
		paginator = null;
		pageSize = 10;
		maxPages = 10;
		selectedRecord = null;
		skipDeleteWarning = false;
		selectedRecords = null;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getRecordCount()
	 */
	public abstract int getRecordCount();
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getRecords()
	 */
	public abstract List<R> getRecords();
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#navigationActionPerformed()
	 */
	public abstract boolean navigationActionPerformed();
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#isAlwaysTrue()
	 */
	public boolean isAlwaysTrue() {
		return true;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#setAlwaysTrue(boolean)
	 */
	public void setAlwaysTrue(boolean neverFalse) {
		//
	}

	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getSelectedRecord()
	 */
	public R getSelectedRecord() {
		return selectedRecord;
	}
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#setSelectedRecord(org.quartz.watch.dc.QWControlledRecord)
	 */
	public void setSelectedRecord(R selectedRecord) {
		this.selectedRecord = selectedRecord;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#isSkipDeleteWarning()
	 */
	public boolean isSkipDeleteWarning() {
		return skipDeleteWarning;
	}
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#setSkipDeleteWarning(boolean)
	 */
	public void setSkipDeleteWarning(boolean skipDeleteWarning) {
		this.skipDeleteWarning = skipDeleteWarning;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getPageStart()
	 */
	public int getPageStart() {
		if(getPaginator() != null) {
			return getPaginator().getPageIndex();
		}
		return 0;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getPageSize()
	 */
	public int getPageSize() {
		return pageSize;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#setPageSizeMax()
	 */
	public void setPageSizeMax() {
		pageSize = MAX_RECORD_COUNT;	
		resetStartPage();
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getMaxPages()
	 */
	public int getMaxPages() {
		return maxPages;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getPaginator()
	 */
	public DataPaginator getPaginator() {
		return paginator;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#setPaginator(com.icesoft.faces.component.datapaginator.DataPaginator)
	 */
	public void setPaginator(DataPaginator dp) {
		paginator = dp;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#resetStartPage()
	 */
	public void resetStartPage() {
		if(getPaginator() != null) {
			getPaginator().gotoFirstPage();
		}
		clearSelectedRecords();
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#paginationActionPerformed(javax.faces.event.ActionEvent)
	 */
	public void paginationActionPerformed(ActionEvent ae) {
		clearSelectedRecords();
		PaginatorActionEvent event = (PaginatorActionEvent)ae;
		setPaginator((DataPaginator)event.getSource());
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#changePageSizeActionPerformed(javax.faces.event.ActionEvent)
	 */
	public void changePageSizeActionPerformed(ActionEvent ae) {
		clearSelectedRecords();
		MenuItem item = (MenuItem)ae.getSource();
		try {
			pageSize = Integer.parseInt((String)item.getValue());
		}
		catch(Exception e) {
			QWLogger.getLogger().log(Level.SEVERE, "changePageSizeActionPerformed", e);
		}
		
		resetStartPage();
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#maxPageSizeActionPerformed(javax.faces.event.ActionEvent)
	 */
	public void maxPageSizeActionPerformed(ActionEvent ae) {
		setPageSizeMax();
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getFirstRow()
	 */
	public int getFirstRow() {
		if(getPaginator() != null) {
			return getPaginator().getFirstRow();
		}
		
		return 0;
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#cancelActionPerformed(javax.faces.event.ActionEvent)
	 */
	public void cancelActionPerformed(ActionEvent ae) {
		setSelectedRecord(null);
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#askDeleteRecordActionPerformed(javax.faces.event.ActionEvent)
	 */
	public void askDeleteRecordActionPerformed(ActionEvent ae) {
		if(skipDeleteWarning) {
			removeRecordActionPerformed(ae);
		}
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#removeRecordActionPerformed(javax.faces.event.ActionEvent)
	 */
	public void removeRecordActionPerformed(ActionEvent ae) {
		if(getSelectedRecord() != null) {
			deleteRecord(getSelectedRecord());
			setSelectedRecord(null);
		}
		else {
			for(Iterator<R> iterRec = getRecords().iterator(); iterRec.hasNext();) {
				R nextRec = iterRec.next();
				if(nextRec.isSelected()) {
					iterRec.remove();
				}
			}
			//resetStartPage();
		}	
	}
	
	protected void deleteRecord(R rec) {
		for(Iterator<R> iterRec = getRecords().iterator(); iterRec.hasNext();) {
			R nextRec = iterRec.next();
			if(rec == nextRec) {
				iterRec.remove();
				break;
			}
		}
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getDeleteWarning()
	 */
	public String getDeleteWarning() {
		return "Etes vous sur de supprimer?"; 
	}
	
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#getSelectedRecords()
	 */
	public List<R> getSelectedRecords() {
		if(selectedRecords == null) {
			selectedRecords = new ArrayList<R>();
		}
		return selectedRecords;
	}

	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#setSelectedRecords(java.util.List)
	 */
	public void setSelectedRecords(List<R> selectedRecords) {
		this.selectedRecords = selectedRecords;
	}
	
	protected <T extends R> void addSelectedRecord(T rec) {
		for(Iterator<R> iterRecs = getSelectedRecords().iterator(); iterRecs.hasNext();) {
			if(rec == iterRecs.next()) {
				return;
			}
		}
		
		getSelectedRecords().add(rec);
	}
	
	protected <T extends R> void removeSelectedRecord(T rec) {
		for(Iterator<R> iterRecs = getSelectedRecords().iterator(); iterRecs.hasNext();) {
			if(rec == iterRecs.next()) {
				iterRecs.remove();
				return;
			}
		}
	}
	
	protected void clearSelectedRecords() {
		for(Iterator<R> iterRecs = getSelectedRecords().iterator(); iterRecs.hasNext();) {
			R nextRec = iterRecs.next();
			nextRec.clearSelected();
		}
		selectedRecords = new ArrayList<R>();
	}
	
	/* (non-Javadoc)
	 * @see org.quartz.watch.dc.impl.QWDialogController2#dispose()
	 */
	public void dispose() {
		try {
			clean();
		}
		catch(Exception e) {
			// silent
		}
		System.out.println(this+" disposed, gimp!!!!");
	}
	
	public static class Record<C extends QWAbstractDC<?>> implements QWControlledRecord<C> {
		boolean selected;
		private C controller;
		
		public Record(C controller) {
			this.controller = controller;
		}
		
		/* (non-Javadoc)
		 * @see org.quartz.watch.dc.impl.QWControlledRecord#getRecordController()
		 */
		public C getRecordController() {
			return controller;
		}
		
		/* (non-Javadoc)
		 * @see org.quartz.watch.dc.impl.QWControlledRecord#setRecordController(org.quartz.watch.dc.impl.QWAbstractDC)
		 */
		public void setRecordController(C dc) {
			this.controller = dc;
		}

		/* (non-Javadoc)
		 * @see org.quartz.watch.dc.impl.QWControlledRecord#isSelected()
		 */
		public boolean isSelected() {
			return selected;
		}

		/* (non-Javadoc)
		 * @see org.quartz.watch.dc.impl.QWControlledRecord#setSelected(boolean)
		 */
		public void setSelected(boolean selected) {
			this.selected = selected;
			if(selected) {
				controller.addSelectedRecord(this);
			}
			else {
				controller.removeSelectedRecord(this);
			}
		}
		
		public void clearSelected() {
			selected = false;
		}
	}

}
